/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package uk.ac.rdg.resc.mmd.controllers;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.List;
import uk.ac.rdg.resc.mmd.colocation.NcModelTimeseries;
import uk.ac.rdg.resc.mmd.colocation.ObsProxyData;
import uk.ac.rdg.resc.mmd.ncwms.exceptions.InvalidDimensionValueException;

/**
 *
 * @author Alastair
 */
public class ColocationController {

    private ObsProxyData obs;
    private NcModelTimeseries model;

    public ColocationController(InputStream obsIn, String modelLocation) throws IOException, FileNotFoundException, InvalidDimensionValueException {
        this.obs = new ObsProxyData(obsIn);
        this.model = new NcModelTimeseries(this.obs, modelLocation);
    }

    public void streamTimeseriesChart(OutputStream out, double elevation) throws Exception {
        // Set the ModelTimeseris to have the correct elevation 
        this.model.setElevation(elevation);
        // Generate labels for chart first
        HashMap<String, String> chartLabels = this.getChartLabels();
        // Create Timeseries chart using obs data, model data and labels. Stream out.
        JFreeChartController.streamTimechart(out, this.obs.getData(), this.model.getData(), chartLabels);
    }

    public void streamFlotTimeseriesChart(OutputStream out, double elevation) throws Exception {
        // Set the ModelTimeseris to have the correct elevation
        this.model.setElevation(elevation);
        // Generate labels for chart first
        HashMap<String, String> chartLabels = this.getChartLabels();
        // Create Timeseries Flot chart and associated HTML page using obs data,
        // model data and labels. Stream out.
        FlotController.streamTimechart(out, this.obs.getData(), this.model.getData(), chartLabels);
    }

    public void streamContourPlot(OutputStream out, String deepestDepthStr) throws IOException, InvalidDimensionValueException {
        DepthTimePlotController.getContourPlot(deepestDepthStr, this.model.getAllElevations(),
            this.model.getProfileTimeseriesValues(), this.model.getDates(), out);
    }

    public void streamFilledBlockPlot(OutputStream out, String deepestDepthStr) throws IOException, InvalidDimensionValueException {
        DepthTimePlotController.getFilledBlockPlot(deepestDepthStr, this.model.getAllElevations(),
            this.model.getProfileTimeseriesValues(), this.model.getDates(), out);
    }

    public String getKmlBody(String file, String modelLocation) throws InvalidDimensionValueException, IOException {
        String kmlBody = KmlController.streamKml(this.obs, this.model, file, modelLocation);
        return kmlBody;
    }

    public ObsProxyData getObsProxyData() {
        return this.obs;
    }

    public NcModelTimeseries getNcModelTimeseries() {
        return this.model;
    }

    public String getModelElevationUnits() {
        return this.model.getElevationUnits();
    }

    public List<Double> getModelElevations() throws IOException, InvalidDimensionValueException {
        return this.model.getNonNullElevations();
    }

    public double getModelElevation() {
        return this.model.getElevation();
    }

    private HashMap<String, String> getChartLabels() throws Exception {
        // Create Titles and labels for timeseries chart
        HashMap<String, String> chartLabels = new HashMap<String, String>();
        chartLabels.put("Title", "Obs: Lon: " + this.obs.getLon() + ", Lat: " + this.obs.getLat() +
                ". Model: Lon: " + this.model.getPosition().getX() + ", Lat: "
                + this.model.getPosition().getY() +  ", Depth: " + this.model.getElevation()
                + " " + this.model.getElevationUnits());
        chartLabels.put("ModelYAxisLabel", "Model " + this.model.getParameterName() +
                "(" + this.model.getParameterUnits() + ")");
        chartLabels.put("ObsYAxisLabel", "Obs Proxy Value");

        return chartLabels;
    }
}
